/*
 * This file is part of KubeSphere Console.
 * Copyright (C) 2019 The KubeSphere Console Authors.
 *
 * KubeSphere Console is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * KubeSphere Console is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with KubeSphere Console.  If not, see <https://www.gnu.org/licenses/>.
 */

import React, { Component } from 'react'
import { observer } from 'mobx-react'
import { get } from 'lodash'
// 这是一个专门画图的组件库，在这里画的是蛛网图
import {
  Radar,
  RadarChart,
  PolarGrid,
  PolarAngleAxis,
  PolarRadiusAxis,
} from 'recharts'
import { Loading } from '@kube-design/components'
import { Panel } from 'components/Base'
// 工具类，不知道有什么用
import { getLastMonitoringData } from 'utils/monitoring'
// 从这里拿到数据
import ClusterMonitorStore from 'stores/monitoring/cluster'
// 供测试时使用，尝试在usage组件下增加一个ServiceComponents组件
import ServiceComponents from '../ServiceComponents'
// 页面子组件
import ResourceItem from './ResourceItem'
// 页面的样式
import styles from './index.scss'

// 定义一个类似于全局的字典，用来辅助形成字典
const MetricTypes = {
  cpu_usage: 'cluster_cpu_usage',
  cpu_total: 'cluster_cpu_total',
  memory_usage: 'cluster_memory_usage_wo_cache',
  memory_total: 'cluster_memory_total',
  disk_size_usage: 'cluster_disk_size_usage',
  disk_size_capacity: 'cluster_disk_size_capacity',
  pod_count: 'cluster_pod_running_count',
  pod_capacity: 'cluster_pod_quota',
}
// 从这个最显眼的组件开始上手
@observer
export default class ResourcesUsage extends Component {
  monitorStore = new ClusterMonitorStore({ cluster: this.props.cluster })

  // 组件被挂载的时候调用的函数，内部调用fetchData函数
  // fetchData函数根据MetricTypes来从后端获取数据
  componentDidMount() {
    this.fetchData()
  }

  // 得到需要加载的数据
  get metrics() {
    return this.monitorStore.data
  }

  getValue = data => get(data, 'value[1]', 0)

  fetchData = () => {
    this.monitorStore.fetchMetrics({
      metrics: Object.values(MetricTypes),
      last: true,
    })
  }

  // 相当于形成了一个字典
  getResourceOptions = () => {
    // 获取到数据的最新值，然后重构成键值对的性质
    const data = getLastMonitoringData(this.metrics)
    return [
      {
        name: 'CPU',
        unitType: 'cpu',
        used: this.getValue(data[MetricTypes.cpu_usage]),
        total: this.getValue(data[MetricTypes.cpu_total]),
      },
      {
        name: t('MEMORY'),
        unitType: 'memory',
        used: this.getValue(data[MetricTypes.memory_usage]),
        total: this.getValue(data[MetricTypes.memory_total]),
      },
      {
        name: t('POD'),
        unitType: '',
        used: this.getValue(data[MetricTypes.pod_count]),
        total: this.getValue(data[MetricTypes.pod_capacity]),
      },
      {
        name: t('DISK'),
        unitType: 'disk',
        used: this.getValue(data[MetricTypes.disk_size_usage]),
        total: this.getValue(data[MetricTypes.disk_size_capacity]),
      },
    ]
  }

  getRadarOptions = options =>
    options.map(option => ({
      name: option.name,
      // 为的就是得到一个比例
      usage: Math.round((option.used * 100) / (option.total || option.used)),
    }))

  // 就是拿到组件所需的数据，从而进行渲染
  render() {
    // 获取到了这个字典
    const options = this.getResourceOptions()
    // 对字典进一步处理，从而得到适合雷达图显示的数据
    const radarOptions = this.getRadarOptions(options)
    // 整体的逻辑是一个大组件包一个小组件
    // 尝试将overview中的蛛网图上面的系统组件加入蛛网图组件中
    return (
      <Panel title={t('RESOURCE_USAGE')}>
        {/* 加载这些组件 */}
        <Loading spinning={this.monitorStore.isLoading}>
          <div className={styles.wrapper}>
            <div className={styles.chart}>
              <RadarChart
                cx={180}
                cy={158}
                width={360}
                height={316}
                data={radarOptions}
              >
                <PolarGrid gridType="circle" />
                <PolarAngleAxis dataKey="name" />
                <PolarRadiusAxis domain={[0, 100]} />
                <Radar dataKey="usage" stroke="#345681" fill="#1c2d4267" />
              </RadarChart>
            </div>
            {/* 尝试给组件加标题 */}
            {/* <div className={styles.list} >{t('RESOURCE_ITEM')} */}
            <div className={styles.list}>
              {/* 根据options来计算旁边的每个小组件展示的东西 */}
              {/* map方法可以遍历option数组，对于数组中的每一个属性都返回一个ResourceItem组件 */}
              {options.map(option => (
                <ResourceItem key={option.name} {...option} />
              ))}
            </div>
          </div>
        </Loading>
      </Panel>
    )
  }
}

// //尝试将overview中的蛛网图上面的系统组件加入蛛网图组件中
// return (
//   <Panel title={t('RESOURCE_USAGE')}>
//     {/* 加载这些组件 */}
//     <Loading spinning={this.monitorStore.isLoading}>
//       <div className={styles.wrapper}>
//         <div className={styles.chart}>
//           <RadarChart
//             cx={180}
//             cy={158}
//             width={360}
//             height={316}
//             data={radarOptions}
//           >
//             <PolarGrid gridType="circle" />
//             <PolarAngleAxis dataKey="name" />
//             <PolarRadiusAxis domain={[0, 100]} />
//             <Radar dataKey="usage" stroke="#345681" fill="#1c2d4267" />
//           </RadarChart>
//         </div>
//         <div className={styles.list} >
//           {/* 根据options来计算旁边的每个小组件展示的东西 */}
//           {options.map(option => (
//             <ResourceItem key={option.name} {...option} />
//           ))}
//         </div>
//       </div>
//       {/* 这里是尝试添加的部分 */}
//       <div>
//         <ServiceComponents>
//           {/* 放置ServiceComponent的属性 */}
//         </ServiceComponents>
//       </div>
//     </Loading>
//   </Panel>
// )
